package com.slipper.common.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapperImpl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

public class BeanUtil {
    private static final Logger logger = LoggerFactory.getLogger(BeanUtil.class);

    public static Object getValue(Object object, String fieldName) {
        if (object == null) {
            return "";
        }

        if (object instanceof Map) {
            if (fieldName.indexOf('.') > 0) {
                String[] fieldNames = fieldName.split("\\.", 2);
                return getValue(((Map<?, ?>) object).get(fieldNames[0]), fieldNames[1]);
            } else {
                return ((Map<?, ?>) object).get(fieldName);
            }
        } else {
            if (fieldName.indexOf('.') > 0) {
                String[] fieldNames = fieldName.split("\\.", 2);
                return getValue(new BeanWrapperImpl(object).getPropertyValue(fieldNames[0]), fieldNames[1]);
            } else if (fieldName.contains("loopRow|")) {
                return "";
            } else {
                try {
                    return new BeanWrapperImpl(object).getPropertyValue(fieldName);
                } catch (Exception e) {
                    logger.error("取值失败！", e);
                    return "";
                }
            }
        }
    }

    public static <T> T copy(Object source, Class<T> target) {
        if (source == null || target == null) {
            return null;
        }
        try {
            T newInstance = target.newInstance();
            BeanUtils.copyProperties(source, newInstance);
            return newInstance;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static <T, K> List<K> copyList(List<T> source, Class<K> target) {

        if (null == source || source.isEmpty()) {
            return Collections.emptyList();
        }
        return source.stream().map(e -> copy(e, target)).collect(Collectors.toList());
    }

    public static String getString(Map<String, Object> data, String key) {
        return getString(data, key, null);
    }

    public static String getString(Map<String, Object> data, String key, String defaultValue) {
        if (data == null) {
            return defaultValue;
        }

        if (!data.containsKey(key)) {
            return defaultValue;
        } else {
            Object value = data.get(key);
            return value == null ? null : value.toString();
        }
    }

    public static String[] getStrings(Map<String, Object> data, String key, String[] defaultValue) {
        if (data == null) {
            return defaultValue;
        }

        Object value = data.get(key);
        if (value == null) {
            return defaultValue;
        } else {
            return (String[]) value;
        }
    }

    public static Boolean getBoolean(Map<String, Object> data, String key, Boolean defaultValue) {
        if (data == null) {
            return defaultValue;
        }

        Object value = data.get(key);
        if (value == null) {
            return defaultValue;
        } else {
            return (Boolean) value;
        }
    }

    public static Integer getInteger(Map<String, Object> data, String key, Integer defaultValue) {
        if (data == null) {
            return defaultValue;
        }

        Object value = data.get(key);
        if (StringUtil.isBlank(value)) {
            return defaultValue;
        } else {
            return Integer.parseInt(value.toString());
        }
    }

    public static Integer getInteger(Map<String, Object> data, String key) {
        if (data == null) {
            return null;
        }

        Object value = data.get(key);
        if (StringUtil.isBlank(value)) {
            return null;
        } else {
            return (int) Double.parseDouble(value.toString());
        }
    }

    public static BigDecimal getBigDecimal(Map<String, Object> data, String key, BigDecimal defaultValue) {
        if (data == null) {
            return defaultValue;
        }

        Object value = data.get(key);
        if (StringUtil.isBlank(value)) {
            return defaultValue;
        } else {
            return new BigDecimal(value.toString());
        }
    }

    public static Date getDate(Map<String, Object> data, String key, Date defaultValue) {
        if (data == null) {
            return defaultValue;
        }

        Object value = data.get(key);
        if (!StringUtil.isBlank(value)) {
            try {
                return DateUtil.parseDate(value.toString());
            } catch (Exception e) {
                logger.error("日期转换出错！", e);
            }
        }
        return defaultValue;
    }
}
